package com.enzoism.springboot.dive.chapter01;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 要点一：使用CompletableFuture模拟Callable进行异步请求回调，避免自己定义Callable接口人，然后再使用CompletionService进行结果获取
 * 要点二：CompletableFuture::join/CompletableFuture::get方法区别
 * 要点三：CompletableFuture.supplyAsync()方法使用-同步处理（当前同步是一起并发执行，然后等待所有完成后进行后续操作，不是forEach执行）
 * @link https://blog.csdn.net/qq_28406419/article/details/92787340
 */
public class TestCompleteFuture2 {
    public static void main(String[] args) {
        ExecutorService cachePool = Executors.newCachedThreadPool();
        // 1、测试CompleteFuture
        Set<List<String>> lists = testCompleteFuture(cachePool);
        lists.stream().forEach(item -> item.forEach(innerItem -> System.out.println("----------->" + innerItem)));

        cachePool.shutdown();
    }

    /**
     * 不用再使用Callable进行业务包装了
     */
    public static Set<List<String>> testCompleteFuture(ExecutorService executorService) {
        List<String> list = Arrays.asList("1", "2", "3", "4", "5");

        //采用Stream流的形式进行处理:supplyAsync同步处理
        List<CompletableFuture<List<String>>> dataFutureList = list.stream().map(item -> CompletableFuture
                .supplyAsync(() -> getRestUrlDataList(item), executorService))
                .collect(Collectors.toList());
        return dataFutureList.stream().map(CompletableFuture::join).collect(Collectors.toSet());
    }

    /**
     * 模拟进行业务处理
     */
    private static List<String> getRestUrlDataList(String usrId) {
        try {
            TimeUnit.SECONDS.sleep(Integer.valueOf(usrId));
            return Arrays.asList(usrId, "1111");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return new ArrayList<>();
    }
}
